import fs from 'fs'
import YAML from 'yaml'
import fetch from "node-fetch";
import chokidar from "chokidar"
import { exec } from 'node:child_process'
import plugin from '../../lib/plugins/plugin.js'

let prompt = ''
let inspect = ''
if (process.platform == "win32") {
  prompt = cmd => [`powershell -EncodedCommand ${Buffer.from(`$ProgressPreference="SilentlyContinue";[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;echo "$(prompt)";${cmd}`, "utf-16le").toString("base64")}`]
  inspect = (cmd, data) => data.replace(/\r\n/g, "\n").replace("\n", `${cmd}\n`)
} else if (process.platform == "linux") {
  prompt = cmd => [`"$0" -ic 'echo "\${PS1@P}"';${cmd}`]
  inspect = (cmd, data) => data.replace("\n", `${cmd}\n`)
}

const cfgfile = 'plugins/tools/Yaml/command.yaml'
const cfg = await YAML.parse(fs.readFileSync(cfgfile, "utf8"))
const options = { cwd: cfg.path, shell: cfg.shell, stdio: 'pipe' }

export class linuxshell extends plugin {
    constructor() {
        super({
            name: "Tools Cmd",
            dsc: "执行命令",
            event: "message",
            priority: 600,
            rule: [
               {
                reg: '^rt(.*)$', // run Terminal command
                fnc: 'terminal',
                permission: cfg.permission
               },
               {
                reg: '^rj(.*)$', // run JavaScript code
                fnc: 'javascript',
                permission: cfg.permission
               }
           ]
        })
    }

// Terminal return command
async terminal(e) {
        let msg = e.msg.replace("rt", "")
        if (!msg) return false
        if (cfg.blacklist) {
            logger.debug("检索命令黑名单")
            if (cfg.ban.some(item => msg.includes(item))) {
              e.reply(`${msg}: 该命令在黑名单内`)
              logger.debug(`已拦截黑名单命令: ${msg}`)
              return false
            }
        }
        logger.debug("检索命令通过")
        this.runcmd(e,msg)
        return true
    }

// Terminal run command
async runcmd(e,cmd) {
        logger.debug(`执行命令: ${cmd}`)
        const command = exec(...prompt(cmd), options, function
        (error, stdout, stderr) {
        if (error || stderr) {
            return e.reply(inspect(cmd, stderr))
           } else if (stdout) {
            return e.reply(inspect(cmd, stdout))
           } else {
            return e.reply("任务已完成，无返回", true)
          }
        })
      command.on('close', (code) => {
        if (code == 0){
          logger.debug(`命令 "${cmd}" 返回 *正常* Code: ${code}`)
        } else {
          logger.debug(`命令 "${cmd}" 返回 *异常* Code: ${code}`)
        }
      })
    }

// JavaScript return code
async javascript(e) {
    let msg = e.msg.replace("rj", "")
    if (!msg) return false
    const command = this.evalSync(msg, function (code, error, stdout, stderr) {
    if (error||stderr) {
      logger.debug(`命令 "${msg}" 返回 *异常* Code: ${code}`)
      return e.reply(error)
    } else if (stdout) {
       logger.debug(`命令 "${msg}" 返回 *正常* Code: ${code}`)
      return e.reply(stdout)
    } else {
      return e.reply("任务已完成，无返回", true)
   }
  })
}

// JavaScript run code (TRSS JsScript)
async evalSync(cmd, func) {
    const ret = {}
    try {
      ret.raw = await eval(cmd)
      if (func) ret.stdout = func(ret.raw)
    } catch (err) {
      ret.error = err
    }
    return ret
  }

}

logger.info("[tools] 终端(Terminal) 已加载")